#include "StandardICA.h"

#include "../../inc/tinyxml2.h"

CStandardICA::CStandardICA(int dimension) :
	m_Dimension(dimension),
	m_X(1, dimension),
	m_W(dimension, dimension),
	m_Y(1, dimension)
{
	int size = this->m_Dimension * this->m_Dimension;

	for (int n = 0; n < size; n++)
	{
		this->m_W.GetData()[n] = ::rand() * 0.01 / RAND_MAX;
	}
}

bool CStandardICA::Save(const char * szFileName)
{
	tinyxml2::XMLDocument doc;

	doc.InsertFirstChild(doc.NewDeclaration());

	auto rootElement = doc.NewElement("Standard-ICA-Netword");
	doc.InsertEndChild(rootElement);

	rootElement->SetAttribute("InputDimension", this->m_Dimension);
	
	auto spWeightElement = doc.NewElement("W");

	string s = "";
	for(int n = 0; n < this->m_Dimension * this->m_Dimension; n++)
	{
		s.append(StringUtil::Number2Str(this->m_W.GetData()[n]));
		if (n != this->m_Dimension * this->m_Dimension - 1)
		{
			s.append(",");
		}
	}
	spWeightElement->SetText(s.c_str());

	rootElement->InsertEndChild(spWeightElement);

	return (doc.SaveFile(szFileName) == tinyxml2::XML_SUCCESS);
}

bool CStandardICA::Load(const char * szFileName)
{
	return false;
}

Vector2 CStandardICA::Execute(const Vector2 & InputData)
{
	this->m_X = InputData;

	Matrix2::Multiply(this->m_W, this->m_X, this->m_Y);

	Vector2 res(this->m_Dimension);
	
	for (int i = 0; i < m_Dimension; i++)
	{
		res[i] = this->m_Y.GetData()[i];
	}
	
	return res;
}